/*
 * RPCServer.cpp
 *
 *  Created on: Nov 6, 2015
 *      Author: rpi
 */

#include <iostream>
#include <json/json.h>
#include <jsonrpc.h>

#include "RpcServer.h"

template<typename T>
RpcServer<T>::RpcServer(std::string strIpAddr, unsigned short usPort)
	: _oRpcObj()
	, _tcpServer(strIpAddr, usPort)
	, _pthdServer(NULL)
{
	_blStop = false;
	initialize();
}

template<typename T>
RpcServer<T>::~RpcServer()
{
	finalize();
}

template<typename T>
void RpcServer<T>::addRpcMethod(std::string func)
{
	typename Json::Rpc::RpcMethod<T>::Method method;

	method = _oRpcObj.getRpcMethod(func);
	_tcpServer.AddMethod(new Json::Rpc::RpcMethod<T>(_oRpcObj, method, func));
}

template<typename T>
void RpcServer<T>::runRPCServer(void *pParam)
{
	RpcServer<T> *pThis = (RpcServer *)pParam;

	if(!pThis->_tcpServer.Listen())
	{
		std::cout << "Listen failed" << std::endl;
		exit(EXIT_FAILURE);
	}

	std::cout << "Start JSON-RPC TCP server" << std::endl;

	while(pThis->_blStop == false)
	{
		pThis->_tcpServer.WaitMessage(1000);
	}

	std::cout << "Stop JSON-RPC TCP server" << std::endl;
}

template<typename T>
void RpcServer<T>::initialize()
{
	//Json::Rpc::TcpServer server(std::string("127.0.0.1"), 8086);

	addRpcMethod("getDeviceList");
	addRpcMethod("getInstanceList");
//	server.AddMethod(new Json::Rpc::RpcMethod<MySqlRpc>(mySqlRpc, &MySqlRpc::Notify,
//		std::string("notify")));

	/* server.SetEncapsulatedFormat(Json::Rpc::NETSTRING); */

	if(!_tcpServer.Bind())
	{
		std::cout << "DeviceRPCServer bind failed" << std::endl;
		exit(EXIT_FAILURE);
	}

	_pthdServer = new std::thread(runRPCServer, this);
}

template<typename T>
void RpcServer<T>::finalize()
{
	_blStop = true;
	_pthdServer->join();
	delete _pthdServer;
	_tcpServer.Close();
}
